home *** CD-ROM | disk | FTP | other *** search
/ Maclife 157 / MACLIFE157-2001-09.ISO.7z / MACLIFE157-2001-09.ISO / Linux / MacOS Tools / Other / BootX 1.1.3 (for Old Mac OS) / Sources / src / LowLevelBoot.c < prev    next >
C/C++ Source or Header  |  2001-07-23  |  23KB  |  761 lines

  1. #include <Types.h>
  2. #include <CodeFragments.h>
  3. #include <MixedMode.h>
  4. #include <OSUtils.h>
  5. #include <Processes.h>
  6. #include <Traps.h>
  7. #include <ShutDown.h>
  8. #include <A4Stuff.h>
  9. #include <Video.h>
  10. #include <Palettes.h>
  11. #include <SCSI.h>
  12. #include <Power.h>
  13. #include <Gestalt.h>
  14. #include <LowMem.h>
  15. #include <Displays.h>
  16.  
  17. #include "LowLevelBoot.h"
  18. #include "BootX.h"
  19.  
  20. #define LINUX_LOGO_COLORS        214
  21. #define CLOSE_VIDEO_DRIVERS        1
  22. #define FAKE_DEBUGGER            1
  23. #define FORCE_SCSI_ON            1
  24. #define DO_POWER_MANAGEMENT        1
  25.  
  26. // This code will do the actual boot
  27.  
  28. // Prototypes
  29. void                main(PPCRegisterList* regList, boot_infos_t* bi, void* ppc_glue, UInt32 setupVideo);
  30.  
  31. static pascal void    BootXShutDownProc(void);
  32. static void            PrepareDisplay(void);
  33. static void            RemoveAnyHWCursor(short driverRefNum);
  34. static void            SetDefaultLinuxCTable(short driverRefNum);
  35. static void            GetColorMap(GDHandle device);
  36. static void            SwitchTo8Bits(GDHandle gDevice);
  37. static void            PrepareSCSI(void);
  38. static void            ForceUnmountAllVolumes(void);
  39. static Boolean        TrapAvailable(short theTrap);
  40.  
  41. static void            my_memset(void *dest, int data, UInt32 size);
  42. static Ptr            get_physical(void* ptr);
  43.  
  44.  
  45. // Globals (A4 based)
  46. static PPCRegisterList    gLocalRegList;
  47. static boot_infos_t*    gBootInfos;
  48. static UInt32            gPowerGestalt;
  49. static Boolean            gShutDownDoesUnmount;
  50. static void*            gShutDownPPCGlue;
  51.  
  52. extern unsigned char linux_logo_red[];
  53. extern unsigned char linux_logo_green[];
  54. extern unsigned char linux_logo_blue[];
  55.  
  56. // This extern should be removed once this function is formally defined in Displays.h
  57. extern pascal OSErr DMUseScreenPrefs(Boolean usePrefs, Handle displayState)
  58.  THREEWORDINLINE(0x303C, 0x03EC, 0xABEB);
  59.  
  60.  
  61. // Entry point called by BootX to install the shutdown proc.
  62. void
  63. main(PPCRegisterList* regList, boot_infos_t* bi, void* ppc_glue, UInt32 setupVideo)
  64. {
  65.     long response;
  66.     
  67.     EnterCodeResource();
  68.     
  69.     BlockMoveData(regList, &gLocalRegList, sizeof(PPCRegisterList));
  70.     gBootInfos = bi;
  71.     gShutDownPPCGlue = ppc_glue;
  72.     
  73.     if (Gestalt(gestaltPowerMgrAttr, (long *)&gPowerGestalt) != noErr)
  74.         gPowerGestalt = 0;
  75.         
  76.     gShutDownDoesUnmount = false;
  77.     if ((Gestalt(gestaltShutdownAttributes, &response) == noErr) &&
  78.         ((response & (1 << gestaltShutdownHassdOnBootVolUnmount)) != 0))
  79.         gShutDownDoesUnmount = true;
  80.  
  81.     ShutDwnInstall(BootXShutDownProc, sdRestartOrPower);
  82.     
  83.     if (setupVideo) {
  84.         Handle        displaystate;
  85.         Boolean        displayMgrPresent;
  86.         long        value = 0;
  87.  
  88.         Gestalt(gestaltDisplayMgrAttr,&value);
  89.         displayMgrPresent=value&(1<<gestaltDisplayMgrPresent);
  90.         if (displayMgrPresent) {
  91.             DMBeginConfigureDisplays (&displaystate);    // Tell the world it is about to change
  92.             DMUseScreenPrefs (true, displaystate);        // Make the change
  93.             DMEndConfigureDisplays (displaystate);        // Tell the world the change is over
  94.         }
  95.     }
  96. }
  97.  
  98. inline asm void
  99. DisableInterrupts(void)
  100. {
  101.     ori.w    #0x700, sr
  102. }
  103.  
  104. // The shutdown procedure itself
  105. pascal void
  106. BootXShutDownProc(void)
  107. {
  108.     EventRecord    event;
  109.     
  110.     EnterCodeResource();
  111.  
  112.     SetZone(SystemZone());
  113.     
  114.     // Unmounts all volumes is not done by shudown proc
  115.     if (!gShutDownDoesUnmount || LMGetVCBQHdr()->qHead)
  116.         ForceUnmountAllVolumes();
  117.         
  118.     // Prepare displays (setup colormaps for 8 bits displays, remove HW cursors, ...)
  119.     PrepareDisplay();
  120.     
  121. #if DO_POWER_MANAGEMENT
  122.     // If Power Manager exist, turn on as many things as possible and set processor
  123.     // to maximum speed.
  124.     if (gPowerGestalt & gestaltPMgrExists)
  125.     {
  126.         if (gPowerGestalt & gestaltPMgrCPUIdle)
  127.             DisableIdle();
  128.         if (gPowerGestalt & gestaltPMgrDispatchExists)
  129.         {
  130.             SetSpindownDisable(true);
  131.             SetProcessorSpeed(true);
  132.             SetIntModemState(true);
  133.         }
  134.         AOn();
  135.         BOn();
  136.     }
  137. #endif
  138.     
  139.     // Send some SCSI commands to all busses to make sure SCSI controllers
  140.     // are actually turned ON
  141.     // ### Potentially dangerous, shoud be replaced by a proper fix to the MESH
  142.     //     driver once I know how to turn back this stupid chip back ON on the
  143.     //     wallstreet !
  144. #if FORCE_SCSI_ON
  145.     PrepareSCSI();
  146. #endif
  147.     
  148.     // Leave some time to drivers to settle down
  149.     SystemTask();    
  150.     SystemTask();
  151.  
  152.     // Let MacOS think we are a debugger and switch 68k emulator to supervisor first
  153. #if FAKE_DEBUGGER
  154.     DebuggerEnter();
  155. #endif
  156.     
  157.     // Put the emulator in supervisor mode
  158.     EnterSupervisorMode();
  159.     
  160. #if FAKE_DEBUGGER
  161.     // Poll until no more OS events in the queue (safety)
  162.     do {
  163.         if (event.what == nullEvent)
  164.             break;
  165.         DebuggerPoll();
  166.     }
  167.     while(GetOSEvent(everyEvent, &event) != 0);
  168. #endif    
  169.     
  170.     // New BootX no longer care about logical display.
  171.     gBootInfos->logicalDisplayBase    = gBootInfos->dispDeviceBase;
  172.     
  173.     // Setup the infos for BAT mapping on NuBus */
  174.     if (gBootInfos->architecture & BOOT_ARCH_NUBUS) {
  175.         gLocalRegList.GPR[5] = (UInt32)gBootInfos->dispDeviceBase & 0xFF800000UL;
  176.         gLocalRegList.GPR[11] = 1;
  177.     }
  178.  
  179.     // Switch emulator interrupts off
  180.     DisableInterrupts();
  181.     
  182.     // Reset some pieces of hardware
  183.     ((void(*)(boot_infos_t* bi))gShutDownPPCGlue)(gBootInfos);
  184.     
  185.     // Enter PPC supervisor (and boot kernel)
  186.     EnterPPCSupervisor(&gLocalRegList);
  187.  
  188.     // Should never reach this point
  189. #if FAKE_DEBUGGER
  190.     DebuggerExit();
  191. #endif
  192.  
  193.     DebugStr("¥pShound not get here neither !");
  194. }
  195.  
  196. // This piece of code will unmount all volumes, including the system disk and
  197. // volumes with currently opened files.
  198. void
  199. ForceUnmountAllVolumes(void)
  200. {
  201.     QHdrPtr        vcbQueue;
  202.     VCBPtr        vcb;
  203.     
  204.     vcbQueue = LMGetVCBQHdr();
  205.     while((vcb = (VCBPtr)vcbQueue->qHead) != NULL)
  206.     {
  207.         ParamBlockRec    pb;
  208.         
  209.         my_memset(&pb, 0, sizeof(ParamBlockRec));
  210.         pb.volumeParam.ioVRefNum    = vcb->vcbVRefNum;
  211.         pb.volumeParam.ioNamePtr    = NULL;
  212.         PBUnmountVolImmed(&pb);
  213.     }
  214. }
  215.  
  216. // This routine will walk thru all MacOS displays, remove
  217. // hardware cursors and set colormaps to std linux colors for each
  218. // indexed device.
  219. void
  220. PrepareDisplay(void)
  221. {
  222. #if CLOSE_VIDEO_DRIVERS
  223.     static short        sDriverList[16];
  224.     static Str255        sCFMError;
  225.     CFragConnectionID    driverLoaderLib;
  226.     Ptr                    driverLoaderMain;
  227.     int                    driver_count, i;
  228. #endif
  229.     
  230.     OSErr            err;
  231.     GDHandle        device;
  232.     
  233.     // We get default display infos.
  234.     device = GetMainDevice();
  235.     gBootInfos->dispDeviceRect[0]            = (**(**device).gdPMap).bounds.left;
  236.     gBootInfos->dispDeviceRect[1]            = (**(**device).gdPMap).bounds.top;
  237.     gBootInfos->dispDeviceRect[2]            = (**(**device).gdPMap).bounds.right;
  238.     gBootInfos->dispDeviceRect[3]            = (**(**device).gdPMap).bounds.bottom;
  239.     gBootInfos->dispDeviceDepth                = (**(**device).gdPMap).pixelSize;
  240.     gBootInfos->dispDeviceBase                = (UInt8 *)get_physical((UInt8 *)(**(**device).gdPMap).baseAddr);
  241.     gBootInfos->dispDeviceRowBytes            = (**(**device).gdPMap).rowBytes & 0x3FFF;
  242.     gBootInfos->dispDeviceRegEntryOffset    = NULL; // Not impl. yet
  243.     gBootInfos->logicalDisplayBase            = (UInt8 *)(**(**device).gdPMap).baseAddr;
  244.  
  245.     HideCursor();
  246.  
  247.     // We loop all displays
  248.     device = GetDeviceList();
  249. #if CLOSE_VIDEO_DRIVERS
  250.     driver_count = 0;
  251. #endif
  252.     while(device)
  253.     {
  254.         if (TestDeviceAttribute(device, screenDevice) && !TestDeviceAttribute(device, noDriver))
  255.         {
  256.             short    refNum = (**device).gdRefNum;
  257.  
  258. #if CLOSE_VIDEO_DRIVERS
  259.             int        found;            
  260.             // Add this driver to the list if it was not already in
  261.             found=0;
  262.             for(i=0; i<driver_count; i++)
  263.                 if (sDriverList[i] == refNum)
  264.                 {
  265.                     found = true;
  266.                     break;
  267.                 }
  268.             if (!found)
  269.                 sDriverList[driver_count++] = refNum;
  270. #endif
  271.                 
  272.             // We need to switch to 8 bits since offb.c cannot handle anything else
  273.             // yet. (Only for the main device)
  274.             if (TestDeviceAttribute(device, mainScreen) && ((**(**device).gdPMap).pixelSize < 8))
  275.                 SwitchTo8Bits(device);
  276.             
  277.             // If the device has indexed colors, we install the standard Linux colormap
  278.             if ((**device).gdType == clutType)
  279.                 SetDefaultLinuxCTable(refNum);
  280.                 
  281.             // We try to blank the hardware cursor. Note that most devices will just make
  282.             // a transparent cursor, so it's a good thing, when not using a full-featured
  283.             // linux video driver, to avoid overriding the framebuffer outside of the
  284.             // defined rectangle. The border might actually contain the cursor.
  285.             RemoveAnyHWCursor(refNum);
  286.         }
  287.         device = GetNextDevice(device);
  288.     }
  289.     
  290.     // Get color map for main device
  291.     GetColorMap(GetMainDevice());
  292.     
  293.     HideCursor();
  294.     HideCursor();
  295.  
  296. #if CLOSE_VIDEO_DRIVERS
  297.     err = GetSharedLibrary("¥pDriverLoaderLib", kAnyCFragArch, kReferenceCFrag,
  298.                         &driverLoaderLib, &driverLoaderMain, sCFMError);
  299.     if (err == noErr)
  300.     {
  301.         CFragSymbolClass    removeDrvrClass;
  302.         Ptr                    removeDrvrProc;
  303.         
  304.         err = FindSymbol(driverLoaderLib, "¥pRemoveDriver", &removeDrvrProc, &removeDrvrClass);
  305.         if (err == noErr)
  306.         {
  307.             enum
  308.             {
  309.                 uppRemoveDriverProcInfo = kCStackBased
  310.                     | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  311.                     | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short)))
  312.                     | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Boolean)))
  313.             };
  314.             
  315.             UniversalProcPtr    removeDriverUPP = 
  316.                 NewRoutineDescriptorTrap(    (ProcPtr)removeDrvrProc,
  317.                                              uppRemoveDriverProcInfo,
  318.                                             kPowerPCISA);
  319.             
  320.             // Close all video drivers
  321.             for (i=0; i<driver_count; i++)
  322.             {
  323.                 CloseDriver(sDriverList[i]);
  324.                 ((OSErr (*)(short, Boolean))(removeDriverUPP))(sDriverList[i], false);
  325.             }
  326.         }
  327.     }
  328. #endif
  329. }
  330.  
  331.  
  332. // Gather some infos about the current MacOS main display. This function
  333. // was originally in BootX.c (get_display_infos)
  334. void
  335. GetColorMap(GDHandle device)
  336. {
  337.     if ((**device).gdType == clutType)
  338.     {
  339.         unsigned short*        colors = (unsigned short*)(((unsigned long)gBootInfos) + gBootInfos->dispDeviceColorsOffset);
  340.         CntrlParam            param;        
  341.         VDSetEntryRecord    hwGetEntry;
  342.         int                    i;
  343.         OSErr                err;
  344.         static ColorSpec    sTempColors[256];
  345.         
  346.         my_memset(¶m, 0, sizeof(CntrlParam));    
  347.         my_memset(&hwGetEntry, 0, sizeof(VDSetEntryRecord));
  348.         
  349.         param.csCode = cscGetEntries;
  350.         param.ioCRefNum = (**device).gdRefNum;
  351.         hwGetEntry.csTable = sTempColors;
  352.         hwGetEntry.csStart = 0;
  353.         hwGetEntry.csCount = 255;    // csCount is 0 based !!
  354.         *((VDSetEntryRecord **)¶m.csParam[0]) = &hwGetEntry;
  355.         err = PBStatusSync((ParmBlkPtr)¶m);
  356.         if (err == noErr)
  357.             for (i=0; i<256; i++)
  358.             {
  359.                 *(colors++) = sTempColors[i].rgb.red;
  360.                 *(colors++) = sTempColors[i].rgb.green;
  361.                 *(colors++) = sTempColors[i].rgb.blue;
  362.             }
  363.         else
  364.             gBootInfos->dispDeviceColorsOffset = 0;
  365.         
  366.     } else
  367.         gBootInfos->dispDeviceColorsOffset = 0;
  368. }
  369.  
  370. // Here, we switch the display to 8 bits using driver calls
  371. void
  372. SwitchTo8Bits(GDHandle gDevice)
  373. {
  374.     // Lookup the modes supported by he video driver, looking for 8 bits
  375.     CntrlParam                        param;
  376.     VDVideoParametersInfoRec        hwVideoParams;
  377.     VDPageInfo                        hwModeSet;
  378.     VDSwitchInfoRec                    hwModeGet;
  379.     VPBlock                            hwVP;
  380.     short                            i;
  381.     short                            foundDepth;
  382.     OSErr                            err;
  383.     
  384.     my_memset(¶m, 0, sizeof(CntrlParam));    
  385.     my_memset(&hwModeSet, 0, sizeof(VDPageInfo));    
  386.     my_memset(&hwModeGet, 0, sizeof(VDSwitchInfoRec));    
  387.  
  388.         
  389.     param.csCode = cscGetCurMode;
  390.     param.ioCRefNum = (**gDevice).gdRefNum;
  391.     *((VDSwitchInfoRec **)¶m.csParam[0]) = &hwModeGet;
  392.     err = PBStatusSync((ParmBlkPtr)¶m);
  393.     if (err != noErr)
  394.         return;
  395.     
  396.     foundDepth = 0;
  397.     for (i=kDepthMode1; i<=kDepthMode6; i++)
  398.     {
  399.         my_memset(&hwVideoParams, 0, sizeof(VDVideoParametersInfoRec));    
  400.         my_memset(&hwVP, 0, sizeof(VPBlock));    
  401.         hwVideoParams.csDisplayModeID    = hwModeGet.csData;
  402.         hwVideoParams.csDepthMode        = i;
  403.         hwVideoParams.csVPBlockPtr        = &hwVP;
  404.         param.csCode = cscGetVideoParameters;
  405.         param.ioCRefNum = (**gDevice).gdRefNum;
  406.         *((VDVideoParametersInfoRec **)¶m.csParam[0]) = &hwVideoParams;
  407.         err = PBStatusSync((ParmBlkPtr)¶m);
  408.         if (err == noErr)
  409.         {
  410.             if (hwVP.vpPixelSize == 8)
  411.             {
  412.                 foundDepth = i;
  413.                 break;
  414.             }
  415.         }
  416.     }
  417.     if (foundDepth != 0)
  418.     {
  419.         hwModeSet.csMode    = foundDepth;
  420.         hwModeSet.csPage    = 0;
  421.         param.csCode = cscSetMode;
  422.         param.ioCRefNum = (**gDevice).gdRefNum;
  423.         *((VDPageInfo **)¶m.csParam[0]) = &hwModeSet;
  424.         err = PBControlSync((ParmBlkPtr)¶m);
  425.         if (err == noErr)
  426.         {
  427.             (**gDevice).gdType    = clutType;
  428.             (**gDevice).gdMode    = foundDepth;
  429.             gBootInfos->dispDeviceDepth        = hwVP.vpPixelSize;
  430.             gBootInfos->logicalDisplayBase    = (UInt8 *)hwModeSet.csBaseAddr;
  431.             gBootInfos->dispDeviceBase        = (UInt8 *)get_physical((UInt8 *)hwModeSet.csBaseAddr);
  432.             gBootInfos->dispDeviceRowBytes    = hwVP.vpRowBytes & 0x3FFF;
  433.  
  434.         }
  435.     }
  436. }
  437.  
  438.  
  439. // Ask the display driver if it supports hardware cursor and remove it.
  440. void
  441. RemoveAnyHWCursor(short driverRefNum)
  442. {
  443.     CntrlParam                        param;
  444.     VDSupportsHardwareCursorRec        hwCursQuery;
  445.     VDDrawHardwareCursorRec            hwCursSet;
  446.     OSErr                            err;
  447.     void*                            genericPtr;
  448.     
  449.  
  450.     my_memset(¶m, 0, sizeof(CntrlParam));    
  451.     my_memset(&hwCursQuery, 0, sizeof(VDSupportsHardwareCursorRec));    
  452.     my_memset(&hwCursSet, 0, sizeof(VDDrawHardwareCursorRec));    
  453.     param.csCode = cscSupportsHardwareCursor;
  454.     param.ioCRefNum = driverRefNum;
  455.     *((VDSupportsHardwareCursorRec **)¶m.csParam[0]) = &hwCursQuery;
  456.     err = PBStatusSync((ParmBlkPtr)¶m);
  457.     if (err != noErr)
  458.         return;
  459.     
  460.     if (!hwCursQuery.csSupportsHardwareCursor)
  461.         return;
  462.     
  463.     my_memset(¶m, 0, sizeof(CntrlParam));    
  464.     my_memset(&hwCursSet, 0, sizeof(VDDrawHardwareCursorRec));    
  465.     param.csCode = cscDrawHardwareCursor;
  466.     param.ioCRefNum = driverRefNum;
  467.     *((VDDrawHardwareCursorRec **)¶m.csParam[0]) = &hwCursSet;
  468.     err = PBControlSync((ParmBlkPtr)¶m);
  469. }
  470.  
  471. // Install the linux default color map. We use direct driver calls since the
  472. // Palette Manager may prevent us from setting reserved MacOS colors.
  473. void
  474. SetDefaultLinuxCTable(short driverRefNum)
  475. {
  476.     static ColorSpec    sDefaultLinuxColors[]    =
  477.         {    0,    {    0x0000,    0x0000,    0x0000    },
  478.             1,    {    0x0000, 0x0000, 0xaaaa    },
  479.             2,    {    0x0000, 0xaaaa, 0x0000    },
  480.             3,    {    0x0000, 0xaaaa, 0xaaaa    },
  481.             4,    {    0xaaaa, 0x0000, 0x0000    },
  482.             5,    {    0xaaaa, 0x0000, 0xaaaa    },
  483.             6,    {    0xaaaa, 0xaaaa, 0x0000    },
  484.             7,    {    0xaaaa, 0xaaaa, 0xaaaa    },
  485.             8,    {    0x5555, 0x5555, 0x5555    },
  486.             9,    {    0x5555, 0x5555, 0xffff    },
  487.             10,    {    0x5555, 0xffff, 0x5555    },
  488.             11,    {    0x5555, 0xffff, 0xffff    },
  489.             12,    {    0xffff, 0x5555, 0x5555    },
  490.             13,    {    0xffff, 0x5555, 0xffff    },
  491.             14,    {    0xffff, 0xffff, 0x5555    },
  492.             15,    {    0xffff, 0xffff, 0xffff    } };
  493.             
  494.     CntrlParam                        param;
  495.     VDSetEntryRecord                hwSetEntry;
  496.     OSErr                            err;
  497.     unsigned long                    temp;
  498.     ColorSpec*                        logo_colors;
  499.     int                                i;
  500.     my_memset(¶m, 0, sizeof(CntrlParam));    
  501.     my_memset(&hwSetEntry, 0, sizeof(VDSetEntryRecord));
  502.     
  503.     param.csCode = cscSetEntries;
  504.     param.ioCRefNum = driverRefNum;
  505.     hwSetEntry.csTable = sDefaultLinuxColors;
  506.     hwSetEntry.csStart = 0;
  507.     hwSetEntry.csCount = 15;    // csCount is 0 based !!
  508.     *((VDSetEntryRecord **)¶m.csParam[0]) = &hwSetEntry;
  509.     err = PBControlSync((ParmBlkPtr)¶m);
  510.     
  511.     logo_colors = (ColorSpec *)NewPtrSys(sizeof(ColorSpec) * LINUX_LOGO_COLORS);
  512.     if (logo_colors == NULL)
  513.         goto failed;
  514.     for (i=0; i<LINUX_LOGO_COLORS; i++)
  515.     {
  516.         logo_colors[i].value        = i + 32;
  517.         logo_colors[i].rgb.red        = (linux_logo_red[i] << 8) | linux_logo_red[i];
  518.         logo_colors[i].rgb.green    = (linux_logo_green[i] << 8) | linux_logo_green[i]; 
  519.         logo_colors[i].rgb.blue        = (linux_logo_blue[i] << 8) | linux_logo_blue[i]; 
  520.     }
  521.     param.csCode = cscSetEntries;
  522.     param.ioCRefNum = driverRefNum;
  523.     hwSetEntry.csTable = logo_colors;
  524.     hwSetEntry.csStart = 32;
  525.     hwSetEntry.csCount = LINUX_LOGO_COLORS-1;    // csCount is 0 based !!
  526.     *((VDSetEntryRecord **)¶m.csParam[0]) = &hwSetEntry;
  527.     err = PBControlSync((ParmBlkPtr)¶m);
  528.     
  529.     DisposePtr((Ptr)logo_colors);
  530.     
  531. failed:
  532.  
  533.     // Leave some time for the VBL to update the palette
  534.     Delay(10, &temp);
  535. }
  536.  
  537. void
  538. PrepareSCSI(void)
  539. {
  540.     long    bus;
  541.     OSErr    err;
  542.     
  543.     if (!TrapAvailable(_SCSIAtomic))
  544.         return;
  545.         
  546.     bus = 0;
  547.     
  548.     do
  549.     {    
  550.         // Declare it static so it's held for VM
  551.         static    SCSIBusInquiryPB    busInquiryPB;
  552.         static    SCSIResetBusPB        resetPB;
  553.         static    unsigned char        inquiryBuffer[256];
  554.         SCSI_IO*                    pb;
  555.         
  556.         my_memset(&busInquiryPB, 0, sizeof(SCSIBusInquiryPB));
  557.         busInquiryPB.scsiPBLength        = sizeof(SCSIBusInquiryPB);
  558.         busInquiryPB.scsiFunctionCode    = SCSIBusInquiry;
  559.         busInquiryPB.scsiDevice.bus        = bus;    /* Other values are zero    */
  560.         err = SCSIAction((SCSI_PB *) &busInquiryPB);
  561.         if (err != noErr)
  562.             break;
  563.         
  564.         my_memset(&resetPB, 0, sizeof(SCSIResetBusPB));
  565.         resetPB.scsiPBLength            = sizeof(SCSIResetBusPB);
  566.         resetPB.scsiFunctionCode        = SCSIResetBus;
  567.         resetPB.scsiDevice.bus            = bus;
  568.         err = SCSIAction((SCSI_PB *) &resetPB);
  569.         
  570.         pb = (SCSI_IO *)NewPtrSysClear(busInquiryPB.scsiIOpbSize);
  571.         if (pb)
  572.         {
  573.             DeviceIdent    devID;
  574.             
  575.             devID.bus        = bus;
  576.             devID.targetID    = 0;
  577.             devID.LUN        = 0;
  578.             
  579.             pb->scsiPBLength        = busInquiryPB.scsiIOpbSize;
  580.             pb->scsiFunctionCode    = SCSIExecIO;
  581.             pb->scsiTimeout            = 1000;
  582.             pb->scsiDevice            = devID;
  583.             pb->scsiCDBLength        = 6;
  584.             pb->scsiCDB.cdbBytes[0]    = 0x12;    /* device inquiry SCSI command */
  585.             pb->scsiCDB.cdbBytes[4] = sizeof(inquiryBuffer);
  586.             pb->scsiCDB.cdbBytes[1] |= (devID.LUN & 0x03) << 5;
  587.             pb->scsiFlags            = scsiTransferPolled;
  588.             pb->scsiDataPtr            = inquiryBuffer;
  589.             pb->scsiDataLength        = sizeof(inquiryBuffer);
  590.             pb->scsiDataType        = scsiDataBuffer;
  591.             pb->scsiSensePtr        = NULL;
  592.             pb->scsiSenseLength        = 0;
  593.             pb->scsiFlags            = scsiSIMQNoFreeze | scsiDirectionIn | scsiDontDisconnect;
  594.             err = SCSIAction((SCSI_PB *)pb);
  595.             if (err == noErr)
  596.                 err = pb->scsiResult;
  597.             DisposePtr((Ptr)pb);
  598.         }
  599.         
  600.         bus++;
  601.     } while(true);
  602. }
  603.  
  604.  
  605. void
  606. my_memset(void *dest, int data, UInt32 size)
  607. {
  608.     UInt32    i;
  609.     
  610.     for (i=0;i<size;i++)
  611.         ((unsigned char *)dest)[i] = (unsigned char)data;
  612. }
  613.  
  614.  
  615. /* Get the physical address, if possible, of a pointer. Note that
  616.  * we fail silently since we _do_ fail sometimes, like for screen
  617.  * base address. In this case, we just return the original pointer
  618.  */
  619. Ptr
  620. get_physical(void* ptr)
  621. {
  622.     LogicalToPhysicalTable    table;
  623.     unsigned long            count;
  624.     OSErr                    err;
  625.     
  626.     table.logical.address    = ptr;
  627.     table.logical.count        = 1024;
  628.     count = sizeof( table ) / sizeof( MemoryBlock ) - 1;
  629.     
  630.     err = GetPhysical( &table, &count );
  631.     if ( err != noErr)
  632.         return ptr;
  633.     
  634.     return ( Ptr ) ( table.physical[0].address );
  635. }
  636.  
  637.  
  638. /*
  639.  * TrapAvailable (see Inside Mac VI 3-8)
  640.  */
  641. #define NumToolboxTraps() (                                ¥
  642.         (NGetTrapAddress(_InitGraf, ToolTrap)            ¥
  643.                 == NGetTrapAddress(0xAA6E, ToolTrap))    ¥
  644.             ? 0x200 : 0x400                                ¥
  645.     )
  646. #define GetTrapType(theTrap) (                            ¥
  647.         (((theTrap) & 0x0800) != 0) ? ToolTrap : OSTrap    ¥
  648.     )
  649.  
  650. static Boolean
  651. TrapAvailable(short theTrap)
  652. {
  653.         TrapType                trapType;
  654.         
  655.         trapType = GetTrapType(theTrap);
  656.         if (trapType == ToolTrap) {
  657.             theTrap &= 0x07FF;
  658.             if (theTrap >= NumToolboxTraps())
  659.                 theTrap = _Unimplemented;
  660.         }
  661.         return (
  662.             NGetTrapAddress(theTrap, trapType)
  663.             != NGetTrapAddress(_Unimplemented, ToolTrap)
  664.         );
  665. }
  666.  
  667.  
  668.  
  669. unsigned char linux_logo_red[] = {
  670.   0x02, 0x9E, 0xE9, 0xC4, 0x50, 0xC9, 0xC4, 0xE9,
  671.   0x65, 0xE3, 0xC2, 0x25, 0xA4, 0xEC, 0x90, 0xA6,
  672.   0xC4, 0x6A, 0xD1, 0xF3, 0x12, 0xED, 0xA0, 0xC2,
  673.   0xB8, 0xD5, 0xDB, 0xD2, 0x3E, 0x16, 0xEB, 0x54,
  674.   0xA9, 0xCD, 0xF5, 0x0A, 0xBA, 0xB3, 0xDC, 0x74,
  675.   0xCE, 0xF6, 0xD3, 0xC5, 0xEA, 0xB8, 0xED, 0x5E,
  676.   0xE5, 0x26, 0xF4, 0xA9, 0x82, 0x94, 0xE6, 0x38,
  677.   0xF2, 0x0F, 0x7F, 0x49, 0xE5, 0xF4, 0xD3, 0xC3,
  678.   0xC2, 0x1E, 0xD5, 0xC6, 0xA4, 0xFA, 0x0A, 0xBA,
  679.   0xD4, 0xEB, 0xEA, 0xEC, 0xA8, 0xBC, 0xB4, 0xDC,
  680.   0x84, 0xE4, 0xCE, 0xEC, 0x92, 0xCD, 0xDC, 0x8B,
  681.   0xCC, 0x1E, 0xF6, 0xB2, 0x60, 0x2A, 0x96, 0x52,
  682.   0x0F, 0xBD, 0xFA, 0xCC, 0xB8, 0x7A, 0x4C, 0xD2,
  683.   0x06, 0xEF, 0x44, 0x64, 0xF4, 0xBA, 0xCE, 0xE6,
  684.   0x8A, 0x6F, 0x3C, 0x70, 0x7C, 0x9C, 0xBA, 0xDF,
  685.   0x2C, 0x4D, 0x3B, 0xCA, 0xDE, 0xCE, 0xEE, 0x46,
  686.   0x6A, 0xAC, 0x96, 0xE5, 0x96, 0x7A, 0xBA, 0xB6,
  687.   0xE2, 0x7E, 0xAA, 0xC5, 0x96, 0x9E, 0xC2, 0xAA,
  688.   0xDA, 0x35, 0xB6, 0x82, 0x88, 0xBE, 0xC2, 0x9E,
  689.   0xB4, 0xD5, 0xDA, 0x9C, 0xA0, 0xD0, 0xA8, 0xC7,
  690.   0x72, 0xF2, 0xDB, 0x76, 0xDC, 0xBE, 0xAA, 0xF4,
  691.   0x87, 0x2F, 0x53, 0x8E, 0x36, 0xCE, 0xE6, 0xCA,
  692.   0xCB, 0xE4, 0xD6, 0xAA, 0x42, 0x5D, 0xB4, 0x59,
  693.   0x1C, 0xC8, 0x96, 0x6C, 0xDA, 0xCE, 0xE6, 0xCB,
  694.   0x96, 0x16, 0xFA, 0xBE, 0xAE, 0xFE, 0x6E, 0xD6,
  695.   0xCE, 0xB6, 0xE5, 0xED, 0xDB, 0xDC, 0xF4, 0x72,
  696.   0x1F, 0xAE, 0xE6, 0xC2, 0xCA, 0xC4
  697. };
  698.  
  699. unsigned char linux_logo_green[] = {
  700.   0x02, 0x88, 0xC4, 0x85, 0x44, 0xA2, 0xA8, 0xE5,
  701.   0x65, 0xA6, 0xC2, 0x24, 0xA4, 0xB4, 0x62, 0x86,
  702.   0x94, 0x44, 0xD2, 0xB6, 0x12, 0xD4, 0x73, 0x96,
  703.   0x92, 0x95, 0xB2, 0xC2, 0x36, 0x0E, 0xBC, 0x54,
  704.   0x75, 0xA5, 0xF5, 0x0A, 0xB2, 0x83, 0xC2, 0x74,
  705.   0x9B, 0xBD, 0xA2, 0xCA, 0xDA, 0x8C, 0xCB, 0x42,
  706.   0xAC, 0x12, 0xDA, 0x7B, 0x54, 0x94, 0xD2, 0x24,
  707.   0xBE, 0x06, 0x65, 0x33, 0xBB, 0xBC, 0xAB, 0x8C,
  708.   0x92, 0x1E, 0x9B, 0xB6, 0x6E, 0xFB, 0x04, 0xA2,
  709.   0xC8, 0xBD, 0xAD, 0xEC, 0x92, 0xBC, 0x7B, 0x9D,
  710.   0x84, 0xC4, 0xC4, 0xB4, 0x6C, 0x93, 0xA3, 0x5E,
  711.   0x8D, 0x13, 0xD6, 0x82, 0x4C, 0x2A, 0x7A, 0x5A,
  712.   0x0D, 0x82, 0xBB, 0xCC, 0x8B, 0x6A, 0x3C, 0xBE,
  713.   0x06, 0xC4, 0x44, 0x45, 0xDB, 0x96, 0xB6, 0xDE,
  714.   0x8A, 0x4D, 0x3C, 0x5A, 0x7C, 0x9C, 0xAA, 0xCB,
  715.   0x1C, 0x4D, 0x2E, 0xB2, 0xBE, 0xAA, 0xDE, 0x3E,
  716.   0x6A, 0xAC, 0x82, 0xE5, 0x72, 0x62, 0x92, 0x9E,
  717.   0xCA, 0x4A, 0x8E, 0xBE, 0x86, 0x6B, 0xAA, 0x9A,
  718.   0xBE, 0x34, 0xAB, 0x76, 0x6E, 0x9A, 0x9E, 0x62,
  719.   0x76, 0xCE, 0xD3, 0x92, 0x7C, 0xB8, 0x7E, 0xC6,
  720.   0x5E, 0xE2, 0xC3, 0x54, 0xAA, 0x9E, 0x8A, 0xCA,
  721.   0x63, 0x2D, 0x3B, 0x8E, 0x1A, 0x9E, 0xC2, 0xA6,
  722.   0xCB, 0xDC, 0xD6, 0x8E, 0x26, 0x5C, 0xB4, 0x45,
  723.   0x1C, 0xB8, 0x6E, 0x4C, 0xBC, 0xAE, 0xD6, 0x92,
  724.   0x63, 0x16, 0xF6, 0x8C, 0x7A, 0xFE, 0x6E, 0xBA,
  725.   0xC6, 0x86, 0xAA, 0xAE, 0xDB, 0xA4, 0xD4, 0x56,
  726.   0x0E, 0x6E, 0xB6, 0xB2, 0xBE, 0xBE
  727. };
  728.  
  729.  
  730. unsigned char linux_logo_blue[] = {
  731.   0x04, 0x28, 0x10, 0x0B, 0x14, 0x14, 0x74, 0xC7,
  732.   0x64, 0x0E, 0xC3, 0x24, 0xA4, 0x0C, 0x10, 0x20,
  733.   0x0D, 0x04, 0xD1, 0x0D, 0x13, 0x22, 0x0A, 0x40,
  734.   0x14, 0x0C, 0x11, 0x94, 0x0C, 0x08, 0x0B, 0x56,
  735.   0x09, 0x47, 0xF4, 0x0B, 0x9C, 0x07, 0x54, 0x74,
  736.   0x0F, 0x0C, 0x0F, 0xC7, 0x6C, 0x14, 0x14, 0x11,
  737.   0x0B, 0x04, 0x12, 0x0C, 0x05, 0x94, 0x94, 0x0A,
  738.   0x34, 0x09, 0x14, 0x08, 0x2F, 0x15, 0x19, 0x11,
  739.   0x28, 0x0C, 0x0B, 0x94, 0x08, 0xFA, 0x08, 0x7C,
  740.   0xBC, 0x15, 0x0A, 0xEC, 0x64, 0xBB, 0x0A, 0x0C,
  741.   0x84, 0x2C, 0xA0, 0x15, 0x10, 0x0D, 0x0B, 0x0E,
  742.   0x0A, 0x07, 0x10, 0x3C, 0x24, 0x2C, 0x28, 0x5C,
  743.   0x0A, 0x0D, 0x0A, 0xC1, 0x22, 0x4C, 0x10, 0x94,
  744.   0x04, 0x0F, 0x45, 0x08, 0x31, 0x54, 0x3C, 0xBC,
  745.   0x8C, 0x09, 0x3C, 0x18, 0x7C, 0x9C, 0x7C, 0x91,
  746.   0x0C, 0x4D, 0x17, 0x74, 0x0C, 0x48, 0x9C, 0x3C,
  747.   0x6A, 0xAC, 0x5C, 0xE3, 0x29, 0x3C, 0x2C, 0x7C,
  748.   0x6C, 0x04, 0x14, 0xA9, 0x74, 0x07, 0x2C, 0x74,
  749.   0x4C, 0x34, 0x97, 0x5C, 0x38, 0x0C, 0x5C, 0x04,
  750.   0x0C, 0xBA, 0xBC, 0x78, 0x18, 0x88, 0x24, 0xC2,
  751.   0x3C, 0xB4, 0x87, 0x0C, 0x14, 0x4C, 0x3C, 0x10,
  752.   0x17, 0x2C, 0x0A, 0x8C, 0x04, 0x1C, 0x44, 0x2C,
  753.   0xCD, 0xD8, 0xD4, 0x34, 0x0C, 0x5B, 0xB4, 0x1E,
  754.   0x1D, 0xAC, 0x24, 0x18, 0x20, 0x5C, 0xB4, 0x1C,
  755.   0x09, 0x14, 0xFC, 0x0C, 0x10, 0xFC, 0x6C, 0x7C,
  756.   0xB4, 0x1C, 0x15, 0x17, 0xDB, 0x18, 0x21, 0x24,
  757.   0x04, 0x04, 0x44, 0x8C, 0x8C, 0xB7
  758. };
  759.  
  760.  
  761.